package org.langcom.crypt;

import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Random;

import sun.security.x509.CertAndKeyGen;
import sun.security.x509.X500Name;
import sun.security.x509.X509Key;

public class KeyGen {

	private static final String KEY_ALG_NAME = "DSA"; //$NON-NLS-1$
	private static final int KEY_SIZE = 512;
	private static String SIG_ALG_NAME = "SHA1WithDSA";//$NON-NLS-1$
	private static final int VALIDITY = 365;
	public static final String PIN_EXT = ".pin"; //$NON-NLS-1$
	private X509Certificate sert;
	private X509Key publicKey;

	public String createKey(String login, String password, String storePath) throws IOException, GeneralSecurityException {
		KeyStore keyStore = buildKeyStore(login, login + "_" + password, password);
		keyStore.store(new FileOutputStream(storePath), password.toCharArray());
		return CryptUtilities.encode64(publicKey.getEncoded());
	}

	public String getPass(String input) {
		byte[] bytes = CryptUtilities.decode64(input);
		return "";
	}

	private KeyStore buildKeyStore(String userName, String dname, String passwordString) throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, IOException, InvalidKeyException, SignatureException, NoSuchProviderException {
		char[] passwordArray = CryptUtilities.digest(passwordString).toCharArray();
		KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
		keyStore.load(null, null);
		checkAlgValidity();
		CertAndKeyGen certandkeygen = new CertAndKeyGen(KEY_ALG_NAME, SIG_ALG_NAME);
		certandkeygen.generate(KEY_SIZE);
		publicKey = certandkeygen.getPublicKey();
		sert = certandkeygen.getSelfCertificate(new X500Name(dname), VALIDITY * 24 * 60 * 60);
		keyStore.setKeyEntry(userName, certandkeygen.getPrivateKey(), passwordArray, new Certificate[] {
			sert
		});
		return keyStore;
	}

	private void savePassword(String storePath, String passwordString) throws IOException {
		BufferedWriter out = new BufferedWriter(new FileWriter(storePath + PIN_EXT));
		out.write(passwordString);
		out.close();
	}

	public static String getRandomPIN() {
		String res = String.valueOf(new Random().nextInt());
		res = res.substring(res.length() - 6, res.length());
		return res;
	}

	private void checkAlgValidity() throws KeyStoreException {
		if (KEY_ALG_NAME.equalsIgnoreCase("DSA")) //$NON-NLS-1$
			SIG_ALG_NAME = "SHA1WithDSA";//$NON-NLS-1$
		else if (KEY_ALG_NAME.equalsIgnoreCase("RSA"))//$NON-NLS-1$
			SIG_ALG_NAME = "MD5WithRSA";//$NON-NLS-1$
		else
			throw new KeyStoreException("Cannot derive signature algorithm");//$NON-NLS-1$
	}
}
